﻿using AiXiu.Common;
using AiXiu.DAL;
using AiXiu.IBLL;
using AiXiu.IDAL;
using AiXiu.Model;
using AiXiu.Model.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AiXiu.BLL
{
    public class UserManager : IUserManager
    {
        /// <summary>
        /// 根据视频Id删除视频
        /// </summary>
        /// <param name="videoId"></param>
        public void DeleteVideo(string videoId)
        {
            //从数据库删除视频
            IUserService userService = new UserService();
            userService.DeleteVideo(videoId);
            //从阿里云删除视频
            VodHelper vodHelper = new VodHelper();
            List<string> videoids = new List<string>();
            videoids.Add(videoId);
            vodHelper.DeleteVideos(videoids);
        }

        /// <summary>
        /// 更新用户头像
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        public OperResult<TBUsers> EditAvatar(TBUsers users)
        {
            IUserService userService = new UserService();
            try
            {
                TBUsers tBUsers = userService.EditAvatar(users);
                return OperResult<TBUsers>.Succeed(tBUsers);
            }
            catch (Exception ex)
            {
                return OperResult<TBUsers>.Failed(ex.ToString());
            }
        }

        /// <summary>
        /// 更新除头像外其他个人信息
        /// </summary>
        /// <param name="users"></param>
        /// <returns></returns>
        public OperResult<TBUsers> EditwithoutAvatar(TBUsers users)
        {
            IUserService userService = new UserService();
            try
            {
                TBUsers tBUsers = userService.EditwithoutAvatar(users);
                return OperResult<TBUsers>.Succeed(tBUsers);
            }
            catch (Exception ex)
            {
                return OperResult<TBUsers>.Failed(ex.ToString());
            }
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public OperResult<TBUsers> GetUser(int userId)
        {
            IUserService userService = new UserService();
            TBUsers tBUsers = userService.FindByUserId(userId);
            return OperResult<TBUsers>.Succeed(tBUsers);

        }

        /// <summary>
        /// 通过视频id获取视频信息
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <returns>本地数据库视频信息</returns>
        public TBVideos GetVideoByVideoId(string videoId)
        {
            IUserService userService = new UserService();
            TBVideos tBVideos = userService.GetVideoByVideoId(videoId);
            return tBVideos;
        }

        /// <summary>
        /// 查询可播放视频列表
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TBVideos> GetVideos()
        {
            IUserService userService = new UserService();
            return userService.GetVideos();
        }

        /// <summary>
        /// 根据用户id获取视频列表
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public OperResult<List<TBVideos>> GetVideosid(int userId)
        {
            IUserService userService = new UserService();
            //return userService.GetTBVideosByUserId(userId);
            List<TBVideos> videos = userService.GetTBVideosByUserId(userId);
            return OperResult<List<TBVideos>>.Succeed(videos);
        }

        /// <summary>
        /// 初始化播放
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <returns>阿里云视频信息</returns>
        public GetPlayInfoResult InitPlay(string videoId)
        {
            IUserService userService = new UserService();
            GetPlayInfoResult getPlayInfoResult = userService.GetPlayInfo(videoId);
            return getPlayInfoResult;
        }

        /// <summary>
        /// 通过手机号登录
        /// </summary>
        /// <param name="mobile">手机号</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public OperResult<TBUsers> LoginByMobile(string mobile, string password)
        {
            //判断手机号和密码是否为空
            if (string.IsNullOrWhiteSpace(mobile) || string.IsNullOrWhiteSpace(password))
            {
                return OperResult<TBUsers>.Failed("手机号密码不能为空");
            }
            IUserService userService = new UserService();
            //判断手机号是否存在
            TBLogins tBLogins = userService.FindByMobile(mobile);
            if (tBLogins == null)
            {
                return OperResult<TBUsers>.Failed("手机号不存在");
            }
            //判断用户密码是否正确
            SHAEncryption sHAEncryption = new SHAEncryption();
            if (sHAEncryption.SHA1Encrypt(password) != (tBLogins.Password))
            {
                return OperResult<TBUsers>.Failed("密码错误");
            }
            //查找用户信息
            TBUsers tBUsers = userService.FindByUserId(tBLogins.Id);
            return OperResult<TBUsers>.Succeed(tBUsers);
        }

        /// <summary>
        /// 通过用户名登录
        /// </summary>
        /// <param name="usrtName">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        public OperResult<TBUsers> LoginByUserName(string usrtName, string password)
        {
            //判断用户名和密码是否为空
            if (string.IsNullOrWhiteSpace(usrtName) || string.IsNullOrWhiteSpace(password))
            {
                return OperResult<TBUsers>.Failed("用户名密码不能为空");
            }
            //通过用户名和密码查找用户是否存在
            IUserService userService = new UserService();
            //判断用户名是否存在
            TBLogins tBLogins = userService.FindByUserName(usrtName);
            if (tBLogins == null)
            {
                return OperResult<TBUsers>.Failed("用户名不存在");
            }
            //判断用户密码是否正确
            SHAEncryption sHAEncryption = new SHAEncryption();
            if (sHAEncryption.SHA1Encrypt(password) != (tBLogins.Password))
            {
                return OperResult<TBUsers>.Failed("密码错误");
            }
            //查找用户信息
            TBUsers tBUsers = userService.FindByUserId(tBLogins.Id);
            return OperResult<TBUsers>.Succeed(tBUsers);
        }

        /// <summary>
        /// 注册用户
        /// </summary>
        /// <returns></returns>
        public OperResult Reg(TBLogins tBLogins)
        {
            //OperResult operResult = new OperResult();
            if (string.IsNullOrWhiteSpace(tBLogins.UserName))
            {
                return OperResult.Failed("用户名不能为空");
            }
            //手机号为空直接返回失败
            if (string.IsNullOrWhiteSpace(tBLogins.MobileNumber))
            {
                return OperResult.Failed("手机号不能为空");
            }
            if (string.IsNullOrWhiteSpace(tBLogins.Password))
            {
                return OperResult.Failed("密码不能为空");
            }
            //实例化UserService类
            IUserService userService = new UserService();
            //判断用户名手机号是否存在
            if (userService.IsSanmeUserName(tBLogins.UserName))
            {
                return OperResult.Failed("用户名存在");
            }
            if (userService.IsSanmeMobile(tBLogins.MobileNumber))
            {
                return OperResult.Failed("手机号存在");
            }
            //实例化SHAEncryption类
            SHAEncryption sHAEncryption = new SHAEncryption();
            //加密用户输入的密码
            tBLogins.Password = sHAEncryption.SHA1Encrypt(tBLogins.Password);
            //判断是否注册成功
            if (userService.AddUser(tBLogins))
            {
                return OperResult.Succeed();
            }
            else
            {
                return OperResult.Failed();
            }

        }

        /// <summary>
        /// 待上传视频
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="fileName">文件名</param>
        /// <param name="headline">标题</param>
        /// <param name="location">位置</param>
        /// <returns></returns>
        public OperResult<CreateUploadVideoResult> ToBeUpload(int userId, string fileName, string headline, string location = null)
        {
            //1、调用方法获取上传凭证
            VodHelper vodHelper = new VodHelper();
            CreateUploadVideoResult result = vodHelper.CreateUploadVideo(headline, fileName);
            //2、视频信息保存到数据库
            IUserService userService = new UserService();
            userService.TOBeUpload(result.VideoId, userId, headline, location);
            return OperResult<CreateUploadVideoResult>.Succeed(result);
        }

        /// <summary>
        /// 同步视频信息
        /// </summary>
        /// <returns></returns>
        public int UpdateVideos()
        {
            //1、调用DAL层方法——获取处理中的视频ld列表
            IUserService userService = new UserService();
            List<string> videoIds = userService.GetInProcessVideoIds();
            //2、如果列表数量大于o，继续，否则返回0
            if (videoIds.Count > 0)
            {
                //3、调用VodHelper中【批量获取视频信息】的方法，获取视频信息结果类GetVideolnfosResult
                VodHelper vodHelper = new VodHelper();
                GetVideoInfosResult result = vodHelper.GetVideoInfos(videoIds);
                //5、调用DAL层方法——批量更新视频信息
                userService.UpdateVideos(result.VideoList);
                return videoIds.Count;
            }
            else
            {
                return 0;
            }



        }

        #region 视频点赞

        private const string KeyPrefix = "VideoLike";

        /// <summary>
        /// 是否已点赞
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <param name="userId">用户id</param>
        /// <returns></returns>
        public bool IsLike(string videoId, int userId)
        {
            string key = $"{KeyPrefix}_{videoId}";
            return RedisHelper.SetContains(key, userId);
        }

        /// <summary>
        /// 添加点赞
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <param name="userId">用户id</param>
        /// <returns></returns>
        public bool AddLike(string videoId, int userId)
        {
            string key = $"{KeyPrefix}_{videoId}";
            return RedisHelper.SetAdd(key, userId);
        }

        /// <summary>
        /// 移除点赞
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <param name="userId">用户id</param>
        /// <returns></returns>
        public bool RemoveLike(string videoId, int userId)
        {
            string key = $"{KeyPrefix}_{videoId}";
            return RedisHelper.SetRemove(key, userId);
        }

        /// <summary>
        /// 显示点赞总数
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <returns></returns>
        public long Count(string videoId)
        {
            string key = $"{KeyPrefix}_{videoId}";
            return RedisHelper.SetLength(key);
        }

        #endregion

        #region 视频评论
        private const string Comment = "VideoDiscuss";

        /// <summary>
        /// 添加评论
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <param name="discuss">评论</param>
        /// <returns></returns>
        public bool Add(string videoId, Discuss discuss)
        {
            string key = $"{Comment}_{videoId}";
            long score = TimeHelper.ConvertDateTimeByUnix(DateTime.Now);
            return RedisHelper.SortedSetAdd(key, discuss, score);
        }

        /// <summary>
        /// 评论计数
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <returns></returns>
        public long Pcount(string videoId)
        {
            string key = $"{Comment}_{videoId}";
            return RedisHelper.SortedSetLength(key);
        }

        /// <summary>
        /// 查询评论列表
        /// </summary>
        /// <param name="videoId">视频id</param>
        /// <param name="pageNumber">页码</param>
        /// <param name="pageSize">数据行</param>
        /// <returns></returns>
        public List<Discuss> QueryDiscusses(string videoId, int pageNumber, int pageSize = 10)
        {
            string key = $"{Comment}_{videoId}";
            int start = (pageNumber - 1) * pageSize;
            int stop = start + pageSize - 1;
            return RedisHelper.SortedSetRangeByRank<Discuss>(key, start, stop, false);
        }

        #endregion

        #region 社交业务管理接口实现

        private const string friendKeyPrefix = "Friend";
        private const string messageKeyPrefix = "Message";

        /// <summary>
        /// 添加好友
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <returns></returns>
        public bool AddFriend(int selfId, int otherId)
        {
            // 查询用户信息
            IUserService userService = new UserService();
            TBUsers self = userService.FindByUserId(selfId);
            TBUsers other = userService.FindByUserId(otherId);
            if (self == null || other == null)
                return false;
            // 聊天Id
            string chatId = Guid.NewGuid().ToString("N");
            // 添加对方到我的好友
            DateTime timeNow = DateTime.Now;
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = new Friend()
            {
                NickName = other.NickName,
                Avatar = other.Avatar,
                LastMessage = new Message()
                {
                    UserId = other.Id,
                    Content = other.NickName,
                    AddTime = timeNow
                },
                ChatId = chatId
            };
            bool selfResult = RedisHelper.HashSet(selfKey, otherId.ToString(), selfFriend);
            // 添加我到对方的好友
            string otherKey = $"{friendKeyPrefix}_{otherId}";
            Friend otherFriend = new Friend()
            {
                NickName = self.NickName,
                Avatar = self.Avatar,
                LastMessage = new Message()
                {
                    UserId = self.Id,
                    Content = self.NickName,
                    AddTime = timeNow
                },
                ChatId = chatId
            };
            bool otherResult = RedisHelper.HashSet(otherKey, selfId.ToString(), otherFriend);
            // 返回结果
            return selfResult && otherResult;
        }

        /// <summary>
        /// 获取好友列表
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <returns></returns>
        public Dictionary<int, Friend> GetFriends(int selfId)
        {
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Dictionary<string, Friend> friendDictionary = RedisHelper.HashGetAll<Friend>(selfKey);
            return friendDictionary.ToDictionary(m => int.Parse(m.Key), m => m.Value);
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <param name="content">消息内容</param>
        /// <returns></returns>
        public bool SendMessage(int selfId, int otherId, string content)
        {
            DateTime timeNow = DateTime.Now;
            //获取聊天Id
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = RedisHelper.HashGet<Friend>(selfKey, otherId.ToString());
            string chatId = selfFriend.ChatId;
            //存储消息到消息列表
            string messageKey = $"{messageKeyPrefix}_{chatId}";
            Message message = new Message()
            {
                UserId = selfId,
                Content = content,
                AddTime = timeNow
            };
            long score = TimeHelper.ConvertDateTimeByUnix(DateTime.Now);
            bool messageResult = RedisHelper.SortedSetAdd(messageKey, message, score);
            //更新最后消息到我的好友列表
            selfFriend.LastMessage = message;
            bool selfResult = RedisHelper.HashSet(selfKey, otherId.ToString(), selfFriend);
            //更新最后消息到对方的好友列表
            string otherKey = $"{friendKeyPrefix}_{otherId}";
            Friend otherFriend = RedisHelper.HashGet<Friend>(otherKey, selfId.ToString());
            otherFriend.LastMessage = message;
            bool otherResult = RedisHelper.HashSet(otherKey, selfId.ToString(), otherFriend);
            //返回结果
            return messageResult && selfResult && otherResult;
        }

        /// <summary>
        /// 获取好友信息
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <returns></returns>
        public Friend GetFriend(int selfId, int otherId)
        {
            // 获取聊天Id
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            Friend selfFriend = RedisHelper.HashGet<Friend>(selfKey, otherId.ToString());
            // 返回结果
            return selfFriend;
        }

        /// <summary>
        /// 获取消息记录
        /// </summary>
        /// <param name="selfId"></param>
        /// <param name="otherId"></param>
        /// <param name="pageNumber"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public List<Message> GetMessages(int selfId, int otherId, int pageNumber, int pageSize = 10)
        {
            // 获取聊天Id
            Friend selfFriend = GetFriend(selfId, otherId);
            string chatId = selfFriend.ChatId;
            // 读取消息记录
            string messageKey = $"{messageKeyPrefix}_{chatId}";
            int start = (pageNumber - 1) * pageSize;
            int stop = start + pageSize - 1;
            List<Message> messageList = RedisHelper.SortedSetRangeByRank<Message>(messageKey, start, stop, false);
            // 返回结果
            return messageList;
        }

        /// <summary>
        /// 是否是好友
        /// </summary>
        /// <param name="selfId">自己的用户Id</param>
        /// <param name="otherId">对方的用户Id</param>
        /// <returns></returns>
        public bool IsFriend(int selfId, int otherId)
        {
            string selfKey = $"{friendKeyPrefix}_{selfId}";
            return RedisHelper.HashExists(selfKey, otherId.ToString());
        }

        #endregion
    }
}

